﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Aeon.Emulator.DebugSupport;
using Aeon.Presentation.Debugger;

namespace Aeon.Emulator.Launcher
{
    /// <summary>
    /// Interaction logic for DebuggerWindow.xaml
    /// </summary>
    public partial class DebuggerWindow : Window
    {
        public static readonly DependencyProperty EmulatorHostProperty = DependencyProperty.Register("EmulatorHost", typeof(EmulatorHost), typeof(DebuggerWindow));
        public static readonly DependencyProperty IsHexFormatProperty = AeonDebug.IsHexFormatProperty.AddOwner(typeof(DebuggerWindow));
        public static readonly DependencyProperty InstructionLogProperty = DependencyProperty.Register("InstructionLog", typeof(InstructionLog), typeof(DebuggerWindow));

        private Disassembler disassembler;

        public DebuggerWindow()
        {
            InitializeComponent();
        }

        public EmulatorHost EmulatorHost
        {
            get { return (EmulatorHost)GetValue(EmulatorHostProperty); }
            set { SetValue(EmulatorHostProperty, value); }
        }
        public bool IsHexFormat
        {
            get { return (bool)GetValue(IsHexFormatProperty); }
            set { SetValue(IsHexFormatProperty, value); }
        }
        [CLSCompliant(false)]
        public InstructionLog InstructionLog
        {
            get { return (InstructionLog)GetValue(InstructionLogProperty); }
            set { SetValue(InstructionLogProperty, value); }
        }

        public void UpdateDebugger()
        {
            var vm = this.EmulatorHost.VirtualMachine;

            this.disassembler = new Disassembler(this.EmulatorHost.VirtualMachine);
            this.disassembler.StartSegment = vm.Processor.CS;
            this.disassembler.StartOffset = vm.Processor.EIP;
            this.disassembler.MaximumInstructions = 1000;

            var disasm = this.disassembler.Instructions;
            if(this.InstructionLog != null)
                disasm = this.InstructionLog.Cast<Instruction>().Concat(disasm);

            this.disassemblyView.InstructionsSource = disasm;
            this.registerView.RegisterSource = vm.Processor;
            this.memoryView.MemorySource = vm.PhysicalMemory;
        }
    }
}
